#include <iostream>
#include <unistd.h>
//#include <thread>
#include <pthread.h>
#include <string>
#include <vector>
#include <cstring>
#include <cerrno>
using namespace std;

#include "Thread.hpp"
using namespace ThreadModule;

//四个线程抢100张电影票
const int threadnum=4;
int g_tickets=100;//g_tickets是没有被保护的共享资源

void routine(int& tickets)
{
   cout<<"new thread,&g_tickets:"<<&g_tickets<<endl;
   while(true)
   {
    if(g_tickets>0)
    {
        usleep(1000);
        printf("get tickte number:%d\n",tickets);
        tickets--;
    }
    else
    {
        break;
    }
   }
   
}
int main()
{
    cout<<"main thread,&g_tickets:"<<&g_tickets<<endl;
    vector<Thread<int>> threads;
    //1.创建一批线程
    for(int i=0;i<threadnum;i++)
    {
        string threadname="thread -" + to_string(i+1);
        threads.emplace_back(routine,g_tickets,threadname);
    }
    //2.启动一批线程
    for(auto& thread:threads)
    {
        thread.Start();
    }
    //3.等待一批线程
    for(auto& thread:threads)
    {
        thread.Join();
        cout<<"wait thread done,threadname:"<<thread.threadname()<<endl;
    }

    return 0;
}



/* c++11 实现多线程
const int threadnum=10;
void threadrun(int& data)
{
    int cnt=data;
    while(cnt)
    {
        cout<<"I am new thread,cnt="<<cnt<<endl;
        sleep(1);
        cnt--;
    }
}
int main()
{
    vector<Thread<int>> threads;
    //1.创建一批线程
    for(int i=0;i<threadnum;i++)
    {
        string threadname="thread -" + to_string(i+1);
        threads.emplace_back(threadrun,10,threadname);
    }
    //2.启动一批线程
    for(auto& thread:threads)
    {
        thread.Start();
    }
    //3.等待一批线程
    for(auto& thread:threads)
    {
        thread.Join();
        cout<<"wait thread done,threadname:"<<thread.threadname()<<endl;
    }

    return 0;
}
*/

/*
//c++11 线程库的封装
#include "Thread.hpp"
using namespace ThreadModule;

void threadrun(int& data)
{
    int cnt=data;
    while(cnt)
    {
        cout<<"I am new thread,cnt="<<cnt<<endl;
        sleep(1);
        cnt--;
    }
}

int main()
{
    Thread<int> t1(threadrun,10);
    t1.Start();
    cout<<"threadname: "<<t1.threadname()<<endl;
    t1.Join();
    cout<<"main thread quit!"<<endl;
    return 0;
}
*/

//线程分离
//主线程不关心新线程的执行结果,主线程/新线程将新线程设置为分离状态
//一旦将线程设置为分离状态,主线程禁止使用pthread_join()操作;否则pthread_join()函数将出错返回;

/*void* threadrun(void* args)
{
    //自身将自身设置为分离状态
    pthread_detach(pthread_self());
    string threadname=static_cast<const char*>(args);
    while(true)
    {
        cout<<threadname<<" is runing"<<endl;
        sleep(1);
    }
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,nullptr,threadrun,(void*)"thread -1");
    sleep(1);
    //pthread_detach(tid);//主线程将新线程设置为分离状态
    cout<<"main thread wait block!"<<endl;
    int retval=pthread_join(tid,nullptr);//出错返回: description message:Invalid argument(非法参数)
    cout<<"main thread wait return,retval="<<retval<<" description message:"<<strerror(retval)<<endl;
    return 0;
}
*/

//示例一:
//主线程将新线程设置为分离状态&&主线程执行任务5s后退出,新线程一直不退出
/*
void* threadrun(void* args)
{
    string threadname=static_cast<const char*>(args);
    while(true)
    {
        cout<<threadname<<" is runing"<<endl;
        sleep(1);
    }
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,nullptr,threadrun,(void*)"thread -1");
    sleep(1);
    pthread_detach(tid);//主线程将新线程设置为分离状态
    int cnt=5;
    while(cnt)
    {
        cout<<"main thread is running!"<<endl;
        sleep(1);
        cnt--;
    }
    return 0;
}
*/
//运行结果:主线程退出,新线程退出
//原因:主线程退出等价于进程退出,进程占有的所有资源(进程地址空间、页表、...)都应该被释放
//虽然新线程处于分离状态,但是依旧与其他线程共享资源,所谓的分离只不过主线程不再关心新线程的执行结果;

//示例二:
//处于分离状态的新线程产生异常,主线程不退出

/*void* threadrun(void* args)
{
    string threadname=static_cast<const char*>(args);
    while(true)
    {
        cout<<threadname<<" is runing,pid:"<<getpid()<<endl;
        sleep(1);
        int a=10;
        a/=0;
    }
}
int main()
{
    pthread_t tid;
    pthread_create(&tid,nullptr,threadrun,(void*)"thread -1");
    sleep(1);
    pthread_detach(tid);//主线程将新线程设置为分离状态
    while(true)
    {
        cout<<"main thread is running,pid:"<<getpid()<<endl;
        sleep(1);
    }
    return 0;
}
*/

//运行结果:新线程诞生异常导致主线程退出
//线程分离的理解总结:线程分离并不是将进程地址空间、页表、代码&&数据全部分开,线程分离只是线程的一种工作状态;
//被分离线程与其他线程底层依旧属于同一个进程,资源依旧共享,只不过主线程不再关心新线程的执行结果,不需要再进行等待而已！！！

//C++11  线程库
//证明:C++11多线程是对原生线程库(pthread)的封装;(mkfile中不带选项 -lpthread)

/*void threadrun(int num)
{
    while (num)
    {
        cout << "I am new thread,num=" << num << endl;
        sleep(1);
        num--;
    }
}
int main()
{
    thread t1(threadrun, 10);
    while (true)
    {
        cout << "I am main thread"<< endl;
        sleep(1);
    }
    t1.join();
    return 0;
} 
*/